/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * HangmanClientUI.java
 *
 * Created on Nov 2, 2011, 8:49:48 PM
 */
package client;

import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

/**
 *
 * @author Igor
 */
public class HangmanClient extends javax.swing.JFrame implements HangmanResponsiveUI{
    /** Creates new form HangmanClient */
    public HangmanClient() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        imageLabel = new javax.swing.JLabel();
        scoresPanel = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        attemptsLeftText = new javax.swing.JTextField();
        totalScoreText = new javax.swing.JTextField();
        gamePanel = new javax.swing.JPanel();
        keyboardPanel = new javax.swing.JPanel();
        aButton = new javax.swing.JButton();
        bButton = new javax.swing.JButton();
        cButton = new javax.swing.JButton();
        dButton = new javax.swing.JButton();
        eButton = new javax.swing.JButton();
        fButton = new javax.swing.JButton();
        gButton = new javax.swing.JButton();
        hButton = new javax.swing.JButton();
        iButton = new javax.swing.JButton();
        jButton = new javax.swing.JButton();
        kButton = new javax.swing.JButton();
        lButton = new javax.swing.JButton();
        mButton = new javax.swing.JButton();
        nButton = new javax.swing.JButton();
        oButton = new javax.swing.JButton();
        pButton = new javax.swing.JButton();
        qButton = new javax.swing.JButton();
        rButton = new javax.swing.JButton();
        sButton = new javax.swing.JButton();
        tButton = new javax.swing.JButton();
        uButton = new javax.swing.JButton();
        vButton = new javax.swing.JButton();
        wButton = new javax.swing.JButton();
        xButton = new javax.swing.JButton();
        yButton = new javax.swing.JButton();
        zButton = new javax.swing.JButton();
        wholeWordPanel = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        wholeWordText = new javax.swing.JTextField();
        guessWholeWordButton = new javax.swing.JButton();
        wordLabel = new javax.swing.JLabel();
        menuBar = new javax.swing.JMenuBar();
        gameMenu = new javax.swing.JMenu();
        newGameMenuItem = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        connectMenuItem = new javax.swing.JMenuItem();
        disconnectMenuItem = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        exitMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Hangman");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });
        getContentPane().setLayout(new java.awt.GridBagLayout());

        imageLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        imageLabel.setIcon(new javax.swing.ImageIcon("data\\img\\6.png"));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weighty = 1.0;
        getContentPane().add(imageLabel, gridBagConstraints);

        scoresPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Score"));
        scoresPanel.setLayout(new java.awt.GridBagLayout());

        jLabel2.setText("Attempts left:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        scoresPanel.add(jLabel2, gridBagConstraints);

        jLabel1.setText("Total score:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        scoresPanel.add(jLabel1, gridBagConstraints);

        attemptsLeftText.setEditable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.ipadx = 20;
        gridBagConstraints.weightx = 1.0;
        scoresPanel.add(attemptsLeftText, gridBagConstraints);

        totalScoreText.setEditable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.ipadx = 20;
        gridBagConstraints.weightx = 1.0;
        scoresPanel.add(totalScoreText, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        getContentPane().add(scoresPanel, gridBagConstraints);

        gamePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Guessing"));
        gamePanel.setLayout(new java.awt.BorderLayout(0, 2));

        keyboardPanel.setLayout(new java.awt.GridLayout(2, 0));

        aButton.setText("A");
        aButton.addActionListener(letterListener);
        keyboardPanel.add(aButton);

        bButton.setText("B");
        bButton.addActionListener(letterListener);
        keyboardPanel.add(bButton);

        cButton.setText("C");
        cButton.addActionListener(letterListener);
        keyboardPanel.add(cButton);

        dButton.setText("D");
        dButton.addActionListener(letterListener);
        keyboardPanel.add(dButton);

        eButton.setText("E");
        eButton.addActionListener(letterListener);
        keyboardPanel.add(eButton);

        fButton.setText("F");
        fButton.addActionListener(letterListener);
        keyboardPanel.add(fButton);

        gButton.setText("G");
        gButton.addActionListener(letterListener);
        keyboardPanel.add(gButton);

        hButton.setText("H");
        hButton.addActionListener(letterListener);
        keyboardPanel.add(hButton);

        iButton.setText("I");
        iButton.addActionListener(letterListener);
        keyboardPanel.add(iButton);

        jButton.setText("J");
        jButton.addActionListener(letterListener);
        keyboardPanel.add(jButton);

        kButton.setText("K");
        kButton.addActionListener(letterListener);
        keyboardPanel.add(kButton);

        lButton.setText("L");
        lButton.addActionListener(letterListener);
        keyboardPanel.add(lButton);

        mButton.setText("M");
        mButton.addActionListener(letterListener);
        keyboardPanel.add(mButton);

        nButton.setText("N");
        nButton.addActionListener(letterListener);
        keyboardPanel.add(nButton);

        oButton.setText("O");
        oButton.addActionListener(letterListener);
        keyboardPanel.add(oButton);

        pButton.setText("P");
        pButton.addActionListener(letterListener);
        keyboardPanel.add(pButton);

        qButton.setText("Q");
        qButton.addActionListener(letterListener);
        keyboardPanel.add(qButton);

        rButton.setText("R");
        rButton.addActionListener(letterListener);
        keyboardPanel.add(rButton);

        sButton.setText("S");
        sButton.addActionListener(letterListener);
        keyboardPanel.add(sButton);

        tButton.setText("T");
        tButton.addActionListener(letterListener);
        keyboardPanel.add(tButton);

        uButton.setText("U");
        uButton.addActionListener(letterListener);
        keyboardPanel.add(uButton);

        vButton.setText("V");
        vButton.addActionListener(letterListener);
        keyboardPanel.add(vButton);

        wButton.setText("W");
        wButton.addActionListener(letterListener);
        keyboardPanel.add(wButton);

        xButton.setText("X");
        xButton.addActionListener(letterListener);
        keyboardPanel.add(xButton);

        yButton.setText("Y");
        yButton.addActionListener(letterListener);
        keyboardPanel.add(yButton);

        zButton.setText("Z");
        zButton.addActionListener(letterListener);
        keyboardPanel.add(zButton);

        gamePanel.add(keyboardPanel, java.awt.BorderLayout.CENTER);

        wholeWordPanel.setLayout(new javax.swing.BoxLayout(wholeWordPanel, javax.swing.BoxLayout.LINE_AXIS));

        jLabel3.setText("Whole word:");
        wholeWordPanel.add(jLabel3);

        wholeWordText.addActionListener(wholeWordListener);
        wholeWordText.setFont(new java.awt.Font("Tahoma", 1, 14));
        wholeWordText.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        wholeWordPanel.add(wholeWordText);

        guessWholeWordButton.addActionListener(wholeWordListener);
        guessWholeWordButton.setText("Guess");
        wholeWordPanel.add(guessWholeWordButton);

        gamePanel.add(wholeWordPanel, java.awt.BorderLayout.SOUTH);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        getContentPane().add(gamePanel, gridBagConstraints);

        wordLabel.setFont(new java.awt.Font("Tahoma", 1, 36));
        wordLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        wordLabel.setText("-----------");
        wordLabel.setBorder(javax.swing.BorderFactory.createTitledBorder(""));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        getContentPane().add(wordLabel, gridBagConstraints);

        gameMenu.setText("Game");

        newGameMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F2, 0));
        newGameMenuItem.setText("New Game");
        newGameMenuItem.setEnabled(false);
        newGameMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newGameMenuItemActionPerformed(evt);
            }
        });
        gameMenu.add(newGameMenuItem);
        gameMenu.add(jSeparator2);

        connectMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F5, 0));
        connectMenuItem.setText("Connect...");
        connectMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                connectMenuItemActionPerformed(evt);
            }
        });
        gameMenu.add(connectMenuItem);

        disconnectMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F9, 0));
        disconnectMenuItem.setText("Disconnect");
        disconnectMenuItem.setEnabled(false);
        disconnectMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                disconnectMenuItemActionPerformed(evt);
            }
        });
        gameMenu.add(disconnectMenuItem);
        gameMenu.add(jSeparator1);

        exitMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F12, 0));
        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });
        gameMenu.add(exitMenuItem);

        menuBar.add(gameMenu);

        setJMenuBar(menuBar);

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-724)/2, (screenSize.height-450)/2, 724, 450);
    }// </editor-fold>//GEN-END:initComponents

    private void newGameMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newGameMenuItemActionPerformed
        prepareNewGame();

        Runnable newGameTask = new Runnable() {
            @Override
            public void run() {
                game.newGame();
            }
        };
        (new Thread(newGameTask)).start();
    }//GEN-LAST:event_newGameMenuItemActionPerformed

    private void connectMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_connectMenuItemActionPerformed
        dialog.setVisible(true);
    }//GEN-LAST:event_connectMenuItemActionPerformed

    private void disconnectMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_disconnectMenuItemActionPerformed
        Runnable disconnectTask = new Runnable() {
            @Override
            public void run() {
                game.disconnect();
            }
        };
        (new Thread(disconnectTask)).start();
    }//GEN-LAST:event_disconnectMenuItemActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        Runnable disconnectTask = new Runnable() {
            @Override
            public void run() {
                game.disconnect();
            }
        };
        Thread disconnectThread = new Thread(disconnectTask);
        disconnectThread.start();

        try {
            disconnectThread.join(100);
            System.exit(0);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_formWindowClosing

    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
        Runnable disconnectTask = new Runnable() {
            @Override
            public void run() {
                game.disconnect();
            }
        };
        Thread disconnectThread = new Thread(disconnectTask);
        disconnectThread.start();

        try {
            disconnectThread.join(100);
            System.exit(0);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_exitMenuItemActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(HangmanClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(HangmanClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(HangmanClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(HangmanClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new HangmanClient().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton aButton;
    private javax.swing.JTextField attemptsLeftText;
    private javax.swing.JButton bButton;
    private javax.swing.JButton cButton;
    private javax.swing.JMenuItem connectMenuItem;
    private javax.swing.JButton dButton;
    private javax.swing.JMenuItem disconnectMenuItem;
    private javax.swing.JButton eButton;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JButton fButton;
    private javax.swing.JButton gButton;
    private javax.swing.JMenu gameMenu;
    private javax.swing.JPanel gamePanel;
    private javax.swing.JButton guessWholeWordButton;
    private javax.swing.JButton hButton;
    private javax.swing.JButton iButton;
    private javax.swing.JLabel imageLabel;
    private javax.swing.JButton jButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JPopupMenu.Separator jSeparator2;
    private javax.swing.JButton kButton;
    private javax.swing.JPanel keyboardPanel;
    private javax.swing.JButton lButton;
    private javax.swing.JButton mButton;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JButton nButton;
    private javax.swing.JMenuItem newGameMenuItem;
    private javax.swing.JButton oButton;
    private javax.swing.JButton pButton;
    private javax.swing.JButton qButton;
    private javax.swing.JButton rButton;
    private javax.swing.JButton sButton;
    private javax.swing.JPanel scoresPanel;
    private javax.swing.JButton tButton;
    private javax.swing.JTextField totalScoreText;
    private javax.swing.JButton uButton;
    private javax.swing.JButton vButton;
    private javax.swing.JButton wButton;
    private javax.swing.JPanel wholeWordPanel;
    private javax.swing.JTextField wholeWordText;
    private javax.swing.JLabel wordLabel;
    private javax.swing.JButton xButton;
    private javax.swing.JButton yButton;
    private javax.swing.JButton zButton;
    // End of variables declaration//GEN-END:variables
    //Guessing listeners
    private java.awt.event.ActionListener letterListener = new java.awt.event.ActionListener() {
        @Override
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            javax.swing.JButton button = (javax.swing.JButton) evt.getSource();
            final char letter = button.getText().charAt(0);

            Runnable guessLetterTask = new Runnable() {
                @Override
                public void run() {
                    game.guessLetter(letter);
                }
            };
            (new Thread(guessLetterTask)).start();

            //System.out.println(letter);
            button.setEnabled(false);
        }
    };
    private java.awt.event.ActionListener wholeWordListener = new java.awt.event.ActionListener() {
        @Override
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            final String word = wholeWordText.getText();

            Runnable guessWholeWordTask = new Runnable() {
                @Override
                public void run() {
                    game.guessWord(word);
                }
            };
            (new Thread(guessWholeWordTask)).start();

            wholeWordText.setText("");
        }
    };
    //Connection dialog
    private ConnectDialog dialog = new ConnectDialog(this, true);
    //Game variable declaration
    private HangmanGame game = new HangmanGame(this);

    //Updating interface
    public void prepareNewGame() {
        //enable all letters
        for (java.awt.Component c : keyboardPanel.getComponents()) {
            if (c instanceof javax.swing.JButton) {
                c.setEnabled(true);
            }
        }
    }

    @Override
    public void updateHangmanImage(final int stage) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                imageLabel.setIcon(new javax.swing.ImageIcon("data\\img\\" + stage + ".png"));
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateWordView(final String view) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                wordLabel.setText(view);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateAttemptsLeftCount(final int attemptsLeft) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                attemptsLeftText.setText(Integer.toString(attemptsLeft));
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateTotalScore(final int totalScore) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                totalScoreText.setText(Integer.toString(totalScore));
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateTitle(final String title) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                setTitle(title);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void reportConnectionError() {
        final java.awt.Component c = this;
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                JOptionPane.showMessageDialog(c, "Network connection error", "Error", JOptionPane.ERROR_MESSAGE);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void reportWin() {
        final java.awt.Component c = this;
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                JOptionPane.showMessageDialog(c, "YOU WIN!", "Hangman", JOptionPane.INFORMATION_MESSAGE);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void reportGameOver() {
        final java.awt.Component c = this;
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                JOptionPane.showMessageDialog(c, "YOU LOSE :(", "Hangman", JOptionPane.INFORMATION_MESSAGE);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void connectToServer(final String host, final int port) {
        setTitle("Hangman --- Connecting to server...");

        Runnable connectTask = new Runnable() {
            @Override
            public void run() {
                game.connect(host, port);
            }
        };
        (new Thread(connectTask)).start();
    }

    @Override
    public void connectionEstablished() {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                newGameMenuItem.setEnabled(true);
                disconnectMenuItem.setEnabled(true);
                connectMenuItem.setEnabled(false);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void connectionClosed() {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                newGameMenuItem.setEnabled(false);
                disconnectMenuItem.setEnabled(false);
                connectMenuItem.setEnabled(true);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(HangmanClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
